package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

/**
 * @Classname p1
 * @Description TODO
 * @author cjf
 * @Date 2021/6/22 15:26
 * @Version V1.0
 */

/*
通过内存地址访问Tag的值
*/

type Book struct {
	Title  string
	Author string
	Page   uint
	Tag    []string
}

func main() {
	book := Book{}
	book.Tag = []string{"aaa", "bbb", "ccc"}
	fmt.Println(*(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&book.Tag[0])))))
	fmt.Println(*(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&book.Tag[1])))))
	fmt.Println(*(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&book.Tag[2])))))

	b := Book{Tag: []string{"abc", "def", "hjk"}}

	p := (*[]string)(unsafe.Pointer(uintptr(unsafe.Pointer(&b)) + unsafe.Offsetof(b.Tag)))
	fmt.Println(*p)

	fmt.Printf("%p\n", &b.Tag[0])
	fmt.Printf("%s\n", b.Tag[0])

	h := (*reflect.SliceHeader)(unsafe.Pointer(uintptr(unsafe.Pointer(&b)) + unsafe.Offsetof(b.Tag)))
	fmt.Printf("%p\n", h)

	//ptr := (*string)(unsafe.Pointer(h.Data))
	//fmt.Printf("%p -> %v\n", ptr, *ptr)
	//
	//fmt.Printf("%p\n", &b.Tag[1])
	//ptr1 := (*string)(unsafe.Pointer(h.Data + 16))
	//fmt.Printf("%p -> %v\n", ptr1, *ptr1)
	//
	//fmt.Printf("%p\n", &b.Tag[2])
	//ptr2 := (*[]byte)(unsafe.Pointer(h.Data + 16))
	//fmt.Printf("%p -> %v\n", ptr2, *ptr2)
}

// 可以格式化下输出